using System;
using System.Collections.Generic;
using System.Web;



namespace  Source.Web.FrameWork
{
    public static class Disposer
    {
        private const string DisposalEnabledKey = "_disposeTrackedObjects";
        private const string DisposableObjectsKey = "_disposableObjects";

        public static void EnableDisposalOfTrackedObjects()
        {
            HttpContext.Current.Items[DisposalEnabledKey] = true;
            HttpContext.Current.Items[DisposableObjectsKey] = new List<WeakReference>();
        }

        public static void DisableDisposalOfTrackedObjects()
        {
            HttpContext.Current.Items[DisposalEnabledKey] = false;
            HttpContext.Current.Items[DisposableObjectsKey] = null;
        }

        public static void RegisterForGuaranteedDisposal(IDisposable disposable)
        {
            if (GuaranteedDisposalIsEnabled())
            {
                var disposables = GetTrackedDisposables();
                disposables.Add(new WeakReference(disposable));
            }
        }

        public static void DisposeTrackedReferences()
        {
            var disposables = GetTrackedDisposables();

            foreach (var reference in disposables)
            {
                if (reference.IsAlive)
                {
                    var disposable = reference.Target as IDisposable;
                    if (disposable != null) disposable.Dispose();
                }
            }
        }

        private static bool GuaranteedDisposalIsEnabled()
        {
            var value = HttpContext.Current.Items[DisposalEnabledKey];

            if (value == null)
            {
                return false;
            }

            return (bool)value;
        }

        private static List<WeakReference> GetTrackedDisposables()
        {
            return HttpContext.Current.Items[DisposableObjectsKey] as List<WeakReference> ?? new List<WeakReference>();
        }
    }
}